package in.co.codedoc.struts;

import in.co.codedoc.framework.ServiceInvoker;
import in.co.codedoc.ioc.IOCContainer;
import in.co.codedoc.sql.SessionLocal;

import java.lang.reflect.Method;
import java.util.List;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.StrutsStatics;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.interceptor.PreResultListener;

@SuppressWarnings("serial")
public class CodedocFrameworkInterceptor
	extends AbstractInterceptor
{
	@Override
	public String intercept(ActionInvocation invocation) throws Exception
	{
		try
		{
			SessionLocal.ClearAll();
			
			final ServiceInvoker si = IOCContainer.Lookup(ServiceInvoker.class); 
				
			invocation.addPreResultListener
			(
				new PreResultListener()
				{
					@Override
					public void beforeResult(ActionInvocation invocation, String result)
					{
						final List<Cookie> cookies = si.GetCookies();
						
						for(Cookie cookie:cookies)
						{
							((HttpServletResponse)
									(ActionContext.getContext().get(StrutsStatics.HTTP_RESPONSE)))
									.addCookie(cookie);
						}
					}
				}
			);
			
			String retVal = (String)si.InvokeService
			(
				invocation, actionInvocationInvoke, 
				new Object[]{}, 
				ServletActionContext.getRequest(), ServletActionContext.getResponse(),
				Logger.logger
			);
			
			return retVal;
		}
		finally
		{
			SessionLocal.ClearAll();
		}
	}
	
	private static final Method actionInvocationInvoke = GetActionInvocationInvokeMethod();

	private static Method GetActionInvocationInvokeMethod()
	{
		try
		{
			return ActionInvocation.class.getMethod("invoke", new Class[]{});
		}
		catch (Throwable th)
		{
			throw new RuntimeException(th);
		}
	} 
}
